import { _decorator, Collider2D, Component, Contact2DType, EPhysics2DDrawFlags, IPhysics2DContact, js, Node, PhysicsSystem2D, PolygonCollider2D, Tween, UITransform, Vec3 } from 'cc';
import { Game, GemeType } from '../Game';
import { Block } from '../Block/Block';
const { ccclass, property, requireComponent } = _decorator;

export enum colliderTag {
    None = 0,
    HeroDian = 1000,
    Hero = 1001,
    BlockDian = 10,
    Block = 11,
}

@ccclass('Hero2')
@requireComponent(Collider2D)
export class Hero2 extends Component {
    onEnable() {
        const collider = this.getComponent(Collider2D);
        collider.enabled = true;
        collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }

    /**
     * 当碰撞产生的时候调用
     * @param  {Collider} other 产生碰撞的另一个碰撞组件
     * @param  {Collider} self  产生碰撞的自身的碰撞组件
     */
    private onBeginContact(self: Collider2D, other: Collider2D, contact: IPhysics2DContact | null) {
        var js_block = other.node.parent.getComponent(Block);
        if (!js_block)
            return;
        Game.instance.isGetScore = 1;
        Game.instance.isCollision = true;
        // 获取中心点的位置
        const cententPos = js_block.pos_dianWorldPos;
        // 获取主角的位置
        const heroPos = Game.instance.nodeHero.getPosition();
        var distance = heroPos.subtract(cententPos).length();
        if (distance <= 10) {
            Game.instance.isDoubleScore = true;
            //console.log('主角在障碍物的中心点附近');
            // 在这里处理主角在中心点附近的逻辑
        } else {
            Game.instance.isDoubleScore = false;
            //console.log('主角不在障碍物的中心点附近');
            // 在这里处理主角不在中心点附近的逻辑
        }

        console.error(`碰撞到 ${js_block.index} 标签:${other.tag}  自己标签:${self.tag}`);
        Game.instance.showNextBlock = true;
        if (js_block.index === 1) {
            Game.instance.showNextBlock = false;
        }
        if (Game.instance.lastBlock != null && Game.instance.lastBlock.index === js_block.index) {
            console.error("重复点");
            Game.instance.showNextBlock = false;
        }
        Game.instance.lastBlock = js_block;



        // const isNearEdge = isPointNearPolygonEdge(js_block.Points, heroPos, 10);
        // if (isNearEdge) {
        //     console.error("边缘");
        //     var pos_blockDian = js_block.pos_dianWorldPos;
        //     var pos_hero = Game.instance.nodeHero.getPosition();
        //     var pos_cha = pos_blockDian.subtract(pos_hero);
        //     if (pos_cha.x > 0) {
        //         Game.instance.gameType = GemeType.Over;
        //         const act_1 = new Tween(this.node).to(0.5, { angle: 30 });
        //         new Tween(Game.instance.nodeHero)
        //             .then(act_1)
        //             .call(() => { Game.instance.gameOver(); })
        //             .start();
        //     } else {
        //         Game.instance.gameType = GemeType.Over;
        //         const act_1 = new Tween(this.node).to(0.5, { angle: -30 });
        //         const act_2 = () => { Game.instance.gameOver(); };
        //         new Tween(Game.instance.nodeHero)
        //             .then(act_1)
        //             .call(act_2)
        //             .start();
        //     }
        // } else {
        //     Game.instance.isCollision = true;
        // }

        // if (js_block.score == 0) {
        //     if (other.tag == colliderTag.BlockDian && self.tag == colliderTag.HeroDian) {
        //         js_block.score = 2;
        //         Game.instance.addScore(2);
        //     } else if (other.tag == colliderTag.Block && self.tag == colliderTag.HeroDian) {
        //         js_block.score = 1;
        //         Game.instance.addScore(1);
        //     }
        // }

        // if (Game.instance.isGetScore == -1) {
        //     if (other.tag == colliderTag.BlockDian && self.tag == colliderTag.HeroDian) {
        //         Game.instance.isGetScore = 2;
        //     } else if (other.tag == colliderTag.Block && self.tag == colliderTag.HeroDian) {
        //         Game.instance.isGetScore = 1;
        //     } else if (other.tag == colliderTag.Block && self.tag == colliderTag.Hero) {//判断是否在方块边缘
        //         Game.instance.isGetScore = 0;

        //         var pos_blockDian = js_block.pos_dianWorldPos;
        //         var pos_hero = Game.instance.nodeHero.getPosition();
        //         var pos_cha = pos_blockDian.subtract(pos_hero);
        //         if (pos_cha.x > 0) {
        //             Game.instance.gameType = GemeType.Over;
        //             const act_1 = new Tween(this.node).to(0.5, { angle: 30 });
        //             new Tween(Game.instance.nodeHero)
        //                 .then(act_1)
        //                 .call(() => { Game.instance.gameOver(); })
        //                 .start();
        //         } else {
        //             Game.instance.gameType = GemeType.Over;
        //             const act_1 = new Tween(this.node).to(0.5, { angle: -30 });
        //             const act_2 = () => { Game.instance.gameOver(); };
        //             new Tween(Game.instance.nodeHero)
        //                 .then(act_1)
        //                 .call(act_2)
        //                 .start();
        //         }
        //         console.error('hero滑到');
        //     }
        // }
    }
}
/**
     * 
     * @param points other碰撞点数组
     * @param point 主角判断点
     * @param threshold 距离
     * @returns 
     */
function isPointNearPolygonEdge(points: Vec3[], point: Vec3, threshold: number): boolean {
    const n = points.length; // 多边形顶点的数量
    for (let i = 0; i < n; i++) { // 遍历多边形的每一条边
        const p1 = points[i]; // 当前边的起点
        const p2 = points[(i + 1) % n]; // 当前边的终点（取模确保闭合）

        // 输出当前点到边的距离，用于调试
        console.error("length:" + pointToSegmentDistance(point, p1, p2));

        // 如果点到当前边的距离小于等于阈值，返回 true
        if (pointToSegmentDistance(point, p1, p2) <= threshold) {
            return true;
        }
    }
    // 如果遍历所有边后点都不在任意边附近，返回 false
    return false;
}
function pointToSegmentDistance(p: Vec3, p1: Vec3, p2: Vec3): number {
    const lineLenSquared = p1.subtract(p2).lengthSqr(); // 计算线段长度的平方
    if (lineLenSquared === 0) {
        // 如果线段长度为 0（退化为一个点），返回点到该点的距离
        return p.subtract(p1).length();
    }

    // 计算点 p 在线段上的投影比例 t
    const t = Math.max(0, Math.min(1, p.subtract(p1).dot(p2.subtract(p1)) / lineLenSquared));

    // 根据 t 计算点 p 在线段上的投影点
    const projection = p1.add(p2.subtract(p1).multiplyScalar(t));

    // 返回点 p 到投影点的距离
    return p.subtract(projection).length();
}
